﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Epsilon.Expr
{
    public class FunctionExpr : Expression
    {
        public string Name { get; private set; }
        public List<FunctionArg> Arguments { get; private set; }
        public Type ReturnType { get; private set; }
        public List<Expression> Body { get; private set; }
        public string Guard { get; set; } 

        public List<Type> ArgumentTypes
        {
            get
            {
                List<Type> t = new List<Type>();
                foreach (FunctionArg fa in Arguments)
                    t.Add(fa.Type);
                return t;
            }
        }

        public FunctionExpr(string name, List<FunctionArg> args, Type ret,
            List<Expression> body, int l, int c)
            : base(l, c)
        {
            Name = name;
            Arguments = args;
            ReturnType = ret;
            Body = body;
            Guard = "";
        }
    }

    public class FunctionArg
    {
        public IPattern Pattern { get; private set; }
        public Type Type { get; private set; }

        public FunctionArg(IPattern pattern, Type type)
        {
            Pattern = pattern;
            Type = type;
        }
    }

    public class FunExpr : Expression
    {
        public List<FunctionArg> Arguments { get; private set; }
        public List<Expression> Body { get; private set; }

        public List<Type> ArgumentTypes
        {
            get
            {
                List<Type> t = new List<Type>();
                foreach (FunctionArg fa in Arguments)
                    t.Add(fa.Type);
                return t;
            }
        }

        public FunExpr(List<FunctionArg> args, List<Expression> body, int l, int c)
            : base(l, c)
        {
            Arguments = args;
            Body = body;
        }
    }

    [Serializable]
    public class FunctionException : Exception
    {
        public FunctionException() { }
        public FunctionException(string message) : base(message) { }
        public FunctionException(string message, Exception inner) : base(message, inner) { }
        protected FunctionException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) { }
    }
}
